package com.fairy.sso.client.filter;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.util.ResourceBundle;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Logger;

import com.fairy.sso.Factory;
import com.fairy.sso.SSOSessionFactory;
import com.fairy.sso.client.session.SSOSession;

public class SSOClientFilter implements Filter {
	Logger log = Logger.getLogger(SSOClientFilter.class);
    @Override
    public void destroy() {
    }

	@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpSession httpSession = request.getSession();

        InetAddress addr = InetAddress.getLocalHost();
        String ip=addr.getHostAddress().toString();//获得本机IP
        
        ResourceBundle resource = ResourceBundle.getBundle("sso");
        String  sso_sync_ticket_url=resource.getString("sso.sync.ticket.url");
        
        String  sessionType=resource.getString("session_type");
        
        Factory factory = new SSOSessionFactory();
        factory.setSession(httpSession);
        SSOSession session = factory.getSSOSession(sessionType); 
        
        /**String session_storage_impl_class=resource.getString("session.storage.impl.class");
        
        try {
			ssoSession=((SSOSession)Class.forName(session_storage_impl_class).newInstance());
			
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		};*/
        
        String session_data="userName";
        
        //String accountNo = (String) session.getAttribute(session_data);
        //String accountNo =(String)ssoSession.getData(session_data);
        String accountNo =session.getData(session_data);
        //String ticket = request.getParameter("ticket");
        
        //String domain="www.a.com";
        String key="FAIRY-SSO-KEY";
        Cookie[] cookies = request.getCookies();
        

		
		String sso_server_url = getSsoServerUrl(resource);
        String cookieValue = "";
        if (null != cookies) 
        {
            for (Cookie cookie : cookies) 
            {
                if (key.equals(cookie.getName())) {
                    cookieValue = cookie.getValue();
                    System.out.println(this.getClass().getName()+",cookieValue:"+cookieValue);
                    log.info("cookieValue:"+cookieValue);
                    break;
                }
            }
        }
        String ticket=cookieValue;
        String url = URLEncoder.encode(request.getRequestURL().toString(), "UTF-8");

        if (null == accountNo) 
        {
            if (null != ticket && !"".equals(ticket)) 
            {
            	String sso_url="http://"+sso_sync_ticket_url+"/ticket.do";
            	String param="ticket";
            	String param_value=ticket;
            	//向sso服务器发送ticket获取userName
                accountNo = post( sso_url, param, param_value);
                authAccount(filterChain, request, response, session, session_data, accountNo, sso_server_url, url);
                /**
                if (null != accountNo && !"".equals(accountNo)) 
                {
                	System.out.println(this.getClass().getName()+",从服务端同步数据 "+session_data+":"+accountNo);
                	log.info("从服务端同步数据 "+session_data+":"+accountNo);
                	session.setData(session_data,accountNo);
                    filterChain.doFilter(request, response);
                } 
                else 
                {
                	String jump_url="http://"+sso_server_url+"/index.do?service=" + url;
                	System.out.println(this.getClass().getName()+",向服务端跳转:"+jump_url);
                	log.info("向服务端跳转:"+jump_url);
                    response.sendRedirect(jump_url);
                }
                */
            } 
            else 
            {
            	String sso_url="http://"+sso_sync_ticket_url+"/ip.do";
            	String param="ip";
            	String param_value=ip;
            	accountNo = post( sso_url, param, param_value);
            	//向sso服务器发送ticket获取userName
            	/*
                PostMethod postMethod = new PostMethod(sso_url);
                System.out.println(this.getClass().getName()+",数据同步请求地址:"+sso_url);
                log.info("数据同步请求地址:"+sso_url);
                postMethod.addParameter(param, param_value);
                
                HttpClient httpClient = new HttpClient();
                try {
                    httpClient.executeMethod(postMethod);
                    accountNo = postMethod.getResponseBodyAsString();
                    postMethod.releaseConnection();
                } catch (Exception e) {
                    e.printStackTrace();
                }*/
                authAccount(filterChain, request, response, session, session_data, accountNo, sso_server_url, url);
                //response.sendRedirect("http://"+sso_server_url+"/index.do?service=" + url);
            }
        } 
        else 
        {
            filterChain.doFilter(request, response);
        }
    }

	
	private String post( String sso_url, String param, String param_value) {
		String accountNo="";
		PostMethod postMethod = new PostMethod(sso_url);
		System.out.println(this.getClass().getName()+",数据同步请求地址:"+sso_url);
		log.info("数据同步请求地址:"+sso_url);
		postMethod.addParameter(param, param_value);
		
		HttpClient httpClient = new HttpClient();
		try {
		    httpClient.executeMethod(postMethod);
		    accountNo = postMethod.getResponseBodyAsString();
		    postMethod.releaseConnection();
		} catch (Exception e) {
		    e.printStackTrace();
		}
		return accountNo;
	}

	private void authAccount(FilterChain filterChain, HttpServletRequest request, HttpServletResponse response,
			SSOSession session, String session_data, String accountNo, String sso_server_url, String url)
					throws IOException, ServletException {
		if (null != accountNo && !"".equals(accountNo)) 
		{
			System.out.println(this.getClass().getName()+",从服务端同步数据 "+session_data+":"+accountNo);
			log.info("从服务端同步数据 "+session_data+":"+accountNo);
			session.setData(session_data,accountNo);
		    filterChain.doFilter(request, response);
		} 
		else 
		{
			String jump_url=sso_server_url+"/index.do?service=" + url;
			System.out.println(this.getClass().getName()+",向服务端跳转:"+jump_url);
			log.info("向服务端跳转:"+jump_url);
		    response.sendRedirect(jump_url);
		}
	}

	private String getSsoServerUrl(ResourceBundle resource) 
	{
		String sso_server_url=resource.getString("sso.server.url");
		if(sso_server_url.endsWith("/"))
		{
			sso_server_url=sso_server_url.substring(0, sso_server_url.length()-1);
		}
		if(sso_server_url.startsWith("http://"))
		{
			sso_server_url=sso_server_url.replace("http://", "");
		}
		return sso_server_url;
	}

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}